package com.swm.julie.rest.sausage.annotation;

import java.lang.reflect.Field;
import java.util.ArrayList;

import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field.Index;
import org.apache.lucene.document.Fieldable;

import com.swm.julie.rest.sausage.index.field.Product;

public class ObjectToDocument {

	/**
	 * Convert an anonymous object to Lucene document with reflection information
	 * It supports only primitive type 
	 * @param object
	 * @return
	 * @throws IllegalAccessException 
	 * @throws ClassNotFoundException 
	 */
	public Document toDocument(Object object) throws IllegalAccessException, ClassNotFoundException
	{
		Document doc = new Document();
		Class<?> instance;
		
		instance = Class.forName(object.getClass().getName()); 

		// May be checking annotation at this point //

		/** Get fields of the parameter class then add the field in the document**/
		Field[] fieldList = instance.getDeclaredFields();

		for(Field field : fieldList)
		{
			// name be the field of a Lucene Document
			String name = field.getName(); 

			//check the type of the field for create a field of the document
			Class<?> type = field.getType();
			if(!type.isArray() &&  !type.isAnnotation() && !type.isInterface() && !type.isSynthetic() 
					&& !type.isLocalClass() && !type.isMemberClass() && type.isPrimitive())
			{
				//check an accessibility of the field then set the value for access to the field
				if(!field.isAccessible()) field.setAccessible(true);

				// add the document field to the document
				doc.add(new org.apache.lucene.document.Field
						(name, 
								(String) field.get(object), 
								org.apache.lucene.document.Field.Store.YES, 
								Index.ANALYZED));
			}
		}

		System.out.println("ObjectToDocument.toDocument()");
		return doc;
	}

	public Product toProduct(Document document) throws Exception
	{
		// The first attempt - product class 
		Product product = new Product();
		
		Class pClass;
		//Assume a product class is existence
		try 
		{
			pClass = Class.forName(product.getClass().getName());
		} catch (ClassNotFoundException e) 
		{
			// TODO Auto-generated catch block
			e.printStackTrace();
			throw new Exception("It isn't support type");
		}
		
		// get fields of the object
		Field[] fieldList = pClass.getDeclaredFields();
		// get fields of the document
		ArrayList<Fieldable> docFieldList = (ArrayList<Fieldable>) document.getFields();
		
		// check existence of the each field
		if(!docFieldList.containsAll(docFieldList)) throw new Exception("Field of the document and the object is not compatible.");
		
		for(Fieldable docField : docFieldList)
		{
			org.apache.lucene.document.Field field = (org.apache.lucene.document.Field) docField;
			
			String fieldName = field.name();
			// set accessible to this field
			pClass.getField(fieldName).setAccessible(true);
			pClass.getField(fieldName).set(product, field.stringValue());
		}
		
		return product;
	}
}
